package component.base

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStore
import component.BookViewModel
import component.vm.BaseViewModel


/**
 * 组件接口
 * 管理子component
 */
abstract class BaseComponent<T : BaseViewModel<*>>(
  val viewModelStore: ViewModelStore,
  var lifecycleOwner: LifecycleOwner
) :
  IComponent<T>,
  IComponentLifeCycle {

  private val subContainers: HashMap<Int, BaseComponent<*>> = HashMap()

  abstract fun layoutId(): Int


  override fun setLifeCycleOwner(lifecycleOwner: LifecycleOwner) {
    this.lifecycleOwner = lifecycleOwner
    subContainers.forEach {
      it.value.setLifeCycleOwner(lifecycleOwner)
    }
  }

  override fun getLifeCycleOwner(): LifecycleOwner? {
    return lifecycleOwner
  }

  override fun createVM(viewModelClass: Class<T>): T {
    return ViewModelProvider(viewModelStore, ViewModelFactory())[viewModelClass]
  }


  inner class ViewModelFactory : ViewModelProvider.Factory{
    override fun <X : ViewModel> create(modelClass: Class<X>): X {
      val model = onViewModelCreate(modelClass)
      if (model != null) return model
      return modelClass.newInstance()
    }
  }

  open fun <X : ViewModel>onViewModelCreate(modelClass: Class<X>):X?{
    return null
  }

  protected fun addSubComponent(component: BaseComponent<*>, viewId: Int) {
    if (subContainers.containsKey(viewId)) {
      throw Exception("viewId $viewId already exists")
    }
    this.subContainers[viewId] = component
    lifecycleOwner?.let {
      component.setLifeCycleOwner(it)
    }
    component.init()
  }

  protected fun removeSubComponent(viewId: Int) {
    subContainers.remove(viewId)
  }

  override fun onCreate() {
    subContainers.forEach {
      it.value.onCreate()
    }
  }

  override fun onDestroy() {
    subContainers.forEach {
      it.value.onDestroy()
    }
  }

  override fun onResume() {
    subContainers.forEach {
      it.value.onResume()
    }
  }


  override fun onPause() {
    subContainers.forEach {
      it.value.onPause()
    }
  }

}